from django.shortcuts import render, redirect
# 导包
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
# 导入类视图
from django.views import View

import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入加密库
import hashlib
# 导入图片库
# 绘画库
from PIL import ImageDraw
# 字体库
from PIL import ImageFont
# 图片库
from PIL import Image
# 随机库
import random
# 文件流
import io

import requests

# 导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

# 导入原生sql模块
from django.db import connection

import jwt

# 导入redis数据库
import redis

# 导入时间模块
import time

# 导入公共目录变量
from mydjango.settings import BASE_DIR

# 导包
from django.db.models import Q, F

# 导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from myapp.models import User

from django.utils.deprecation import MiddlewareMixin

from django.http import QueryDict

# 类视图调用
from django.utils.decorators import method_decorator

# 事务操作
from django.db import transaction


# 锁的使用
def testlock(request):
    res = User.objects.get(pk=1)

    if res.num > 0:
        time.sleep(5)
        with connection.cursor() as c:
            c.execute(' update user set num = num - 1 where id = 1 ')
        return HttpResponse("ok")
    else:
        return HttpResponse("钱包为空")


# 并发操作
def TestThread(request):
    res = User.objects.get(pk=1)

    if res.num > 0:
        time.sleep(5)
        # with connection.cursor() as c:
        # 	c.execute('update user set num = num - 1 where id = 1 ')

        # 事务
        try:
            with transaction.atomic():
                res.num = 9
                res.save()
        except ValueError:
            pass

        return HttpResponse("ok")
    else:
        return HttpResponse("库存不足")


# websocket接口
# 客户端列表
clients = {}


@accept_websocket
def websocketlink(request):
    if request.is_websocket():

        userid = str(uuid.uuid1())

        while True:

            message = request.websocket.wait()

            if not message:
                break
            else:
                print('websocket链接成功' + str(message))
                clients[userid] = request.websocket


# 推送消息
def sendmessage(request):
    # 获取消息
    msg = request.GET.get("msg")

    for client in clients:
        clients[client].send(msg.encode('utf-8'))

    return HttpResponse({'message': "ok"})


r = redis.Redis(host="localhost")


# 获取客户端ip
class GetOnLines(APIView):

    def get(self, request):

        if "HTTP_X_FORWARDED_FOR" in request.META:

            ip = request.META.get("HTTP_X_FOGWARDED_FOR")

        else:
            ip = request.META.get("REMOTE_ADDR")

        if r.scard("set_ip"):

            r.sadd("set_ip", ip)
        else:
            r.sadd("set_ip", ip)
            r.expire("set_ip", 30)

        return Response({"online": r.scard("set_ip")})


import time
import hmac
import base64
from hashlib import sha256
import urllib
import json


# 构造钉钉回调方法
def ding_back(request):
    # 获取code
    code = request.GET.get("code")

    t = time.time()
    # 时间戳
    timestamp = str((int(round(t * 1000))))
    appSecret = 'ly-AzMKMmCKQP3geaILT_An32kEfKO3HeOtApy5CgKwjytevVZC0WYsT2gxMB160'
    # 构造签名
    signature = base64.b64encode(
        hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())
    # 请求接口，换取钉钉用户名
    payload = {'tmp_auth_code': code}
    headers = {'Content-Type': 'application/json'}
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=' + urllib.parse.quote(
        signature.decode("utf-8")) + "&timestamp=" + timestamp + "&accessKey=dingoaukgkwqknzjvamdqh",
                        data=json.dumps(payload), headers=headers)

    res_dict = json.loads(res.text)
    print(res_dict)

    # 判断
    user = User.objects.filter(username=res_dict['userinfo']['nick'])

    if user:

        return redirect('http://localhost:8080/staition?uid=' + user.id + "&username=" + user.username)

    else:

        user = User(username=res_dict['userinfo']['nick'])
        user.save()
        user = User.objects.filter(username=res_dict['userinfo']['nick'])

        return redirect('http://localhost:8080/staition?uid=' + user.id + "&username=" + user.username)


# 钉钉
class Dingding:

    def get_url(self, appid, redirect_uri):
        return 'https://oapi.dingtalk.com/connect/qrconnect?appid=' + appid + '&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=' + redirect_uri


# 工厂类
class LoginFactory:

    @staticmethod
    def login_cls(type):
        if type == 'dingding':
            return Dingding()


def dictfetchall(cursor):
    desc = cursor.description
    return [
        dict(zip([col[0] for col in desc], row))

        for row in cursor.fetchall()

    ]


# 执行原生sql
def get_access(request):
    uid = request.GET.get("uid", None)

    # 获取游标对象
    cursor = connection.cursor()

    # 执行sql
    cursor.execute(
        " select a.username,d.nodename from user a left join role b on a.role_id = b.id left join access c on b.id = c.role_id left join node d on c.node_id = d.id ")

    result = dictfetchall(cursor)

    print(result)

    return HttpResponse(json.dumps(result, ensure_ascii=False), content_type='application/json')


# 装饰器
def my_decorator(func):
    def wrapper(request, *args, **kwargs):
        print('装饰器被调用了')

        return func(request, *args, **kwargs)

    return wrapper


# 拼接url
# 构造钉钉登录url
def ding_url(request):
    ding_obj = LoginFactory.login_cls('dingding')
    url = ding_obj.get_url('123', '123')
    return redirect(url)


# appid = 'dingoaukgkwqknzjvamdqh'
# redirect_uri = 'http://localhost:8000/dingding_back/'

# return redirect('https://oapi.dingtalk.com/connect/qrconnect?appid='+appid+'&response_type=code&scope=snsapi_login&state=STATE&redirect_uri='+redirect_uri)

# 注册接口
class Register(APIView):

    def post(self, request):

        # 接收参数
        username = request.POST.get("username", None)

        print(username)

        # 唯一性验证
        try:
            user = User(username=username, password="123")
            user.save()
            response = Response({'message': '注册成功'})
            response["Access-Control-Allow-Origin"] = "http://localhost:8080"
            return response
        except Exception as e:
            print(e)
            response = Response({'message': '注册失败'})
            response["Access-Control-Allow-Origin"] = "http://localhost:8080"
            return response

# def put(self,request):

# 	#接收参数
# 	put = QueryDict(request.body)
# 	username = put.get('username',None)

# @method_decorator(my_decorator)
# def delete(self,request):

# 	put = QueryDict(request.body)
# 	for key,val in put.items():
# 		username = eval(key)['username']


class MyMiddleware(MiddlewareMixin):

    def process_request(self, request):
        pass

    # return HttpResponse(json.dumps({'message':'您没有权限'},ensure_ascii=False))

    def process_view(self, request, view_func, view_args, view_kwargs):
        pass

    def process_exception(self, request, exception):
        pass

    def process_response(self, request, response):
        return response


# 上传类
class UploadFile(View):

    # 上传方法
    def post(self, request):
        # 接收参数
        img = request.FILES.get("file")

        # 建立文件流
        # f = open(os.path.join(UPLOAD_ROOT,'',img.name),'wb')

        # #写文件
        # for chunk in img.chunks():
        # 	f.write(chunk)

        # #关闭文件流
        # f.close()
        with open(os.path.join(UPLOAD_ROOT, '', img.name), 'wb') as f:
            # 写文件
            for chunk in img.chunks():
                f.write(chunk)

        return HttpResponse(json.dumps({'filename': img.name}, ensure_ascii=False), content_type='application/json')


clients = {}  # 创建客户端列表，存储所有在线客户端


@accept_websocket
def link(request):
    # 判断是不是ws请求
    if request.is_websocket():
        userid = str(uuid.uuid1())
        # 判断是否有客户端发来消息，若有则进行处理，若发来“test”表示客户端与服务器建立链接成功
        while True:
            message = request.websocket.wait()
            if not message:
                break
            else:
                print("客户端链接成功：" + str(message, encoding="utf-8"))
                # 保存客户端的ws对象，以便给客户端发送消息,每个客户端分配一个唯一标识
                clients[userid] = request.websocket


# 定义验证码类
class Myc(View):
    # 定义随机颜色方法
    def get_random_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R, G, B)

    # 定义随机验证码
    def get(self, request):
        # 定义画布大小 宽，高
        img_size = (120, 50)
        # 定义画笔 颜色种类,画布，背景颜色
        image = Image.new("RGB", img_size, 'white')
        # 定义画笔对象 图片对象,颜色类型
        draw = ImageDraw.Draw(image, 'RGB')
        # 定义随机字符
        source = '0123456789asdfghjkl'
        # 定义四个字符
        # 定义好容器，用来接收随机字符串
        code_str = ''
        for i in range(4):
            # 获取随机颜色 字体颜色
            text_color = self.get_random_color()
            # 获取随机字符串
            tmp_num = random.randrange(len(source))
            # 获取字符集
            random_str = source[tmp_num]
            # 将随机生成的字符串添加到容器中
            code_str += random_str
            # 将字符画到画布上 坐标，字符串，字符串颜色，字体
            # 导入系统真实字体,字号
            # my_font = ImageFont.truetype("c:\\windows\\Fonts\\arial.ttf",20)
            draw.text((10 + 30 * i, 20)
                      , random_str, text_color)
        # 使用io获取一个缓存区
        buf = io.BytesIO()
        # 将图片保存到缓存区
        image.save(buf, 'png')

        # 将随机码存储到session中
        request.session['code'] = code_str

        # 第二个参数声明头部信息
        return HttpResponse(buf.getvalue(), 'image/png')
